package socket;

//import icons.DrawingIcon;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import socket.ui.Commands;
import socket.ui.UserInterface;

//import view.PaletteController;
//import view.Whiteboard;
//import view.WhiteboardFrame;

/**
 * 
 * @author pfister@lgi2p 07/11/28
 * 
 */
public class Client extends BaseClient implements Commands {
	protected UserInterface ui;
	protected boolean exit;
	protected PrintWriter socketWriter = null;
	
	/**
	 * should be overriden
	 * @param cmd
	 * @param args
	 */
	protected void execCommand(String cmd, String args){
		//System.out.println("command: "+cmd+" args: "+args);
		log("command: "+cmd+" args: "+args);
	}
	
	/**
	 * should be overriden
	 */
	protected void setupUI() {
		log("setupUI");
	}

	public synchronized boolean parseProtocol(String m) {
		String trimmedRemoveKey = REMOVE.trim();
		if (m.contains(trimmedRemoveKey)) {
			// String other = m.substring(trimmedRemoveKey.length()).trim();
			String other = m.substring(0, SEND.length()).trim();
			log(other + " removed");
			return true;
		} else if (m.contains(INCOMING)) {
			String other = m.substring(INCOMING.length()).trim();
			log(other + " incoming");
			return true;
		} else if (m.contains(SEND)) {
			String other = m.substring(0, m.indexOf(SEND)).trim();
			if (!other.equals(name)) {
				String mesg = m.substring(m.indexOf(SEND) + SEND.length())
						.trim();
				mesg = mesg.substring(0, mesg.indexOf(EOM));
				if (mesg.startsWith(EVENT)) {
					mesg = mesg.substring(EVENT.length());
					if (!decodeIncomingEvent(other, mesg))

						log("unknown event from " + other + " : " + mesg);

				} else {
					if (mesg.startsWith(D_CREATE_SHAPE)) {
						String args = m.substring(m.indexOf(D_CREATE_SHAPE) + D_CREATE_SHAPE.length()).trim();
						args = args.substring(0, args.length() - EOM.length())
								.trim();
						execCommand("shape", args);
						log("create shape from " + other + " : " + args);
					} else
						log("message from " + other + " : " + mesg);
				}
			} else
				log("ugh!");
			return true;
		} else if (m.contains(CONNECTED)) {
			log("other clients connected:");
			String clients = m.substring(CONNECTED.length()).trim();
			String[] clts = clients.split(";");
			for (int i = 0; i < clts.length; i++)
				log(clts[i]);
			return true;
		} else
			return false;
	}

	private boolean decodeIncomingEvent(String sender, String mesg) {
		if (sender.equals("foobarbaz")) {
			if (mesg.contains("p_simfail")) {
				ui.logFailures(Integer.parseInt(mesg.substring(10, 11)));
				return true;
			}
		}
		return false;
	}

	public Client(int id, Socket sock, String name) {
		super(id, sock, name);
		try {
			socketWriter = new PrintWriter(sock.getOutputStream(), true);
		} catch (IOException e) {
			System.out.println(ERROR + " c " + e.toString());
		}

	}

	public static void main___(String[] args_) {
		try {
			Socket sock = new Socket("localhost", SERVERPORT);
			Client c = new Client(-1, sock, utils.StringUtils.randomString(5));
			c.run();
			if (c.ui != null && c.exit)
				System.exit(0);
		} catch (UnknownHostException e) {
			System.out.println(ERROR + " 1 " + e.toString());
		} catch (IOException e) {
			System.out.println(ERROR + " 2 " + e.toString());
		} catch (InterruptedException e) {
			System.out.println(ERROR + " 3 " + e.toString());
		} catch (Exception e) {
			System.out.println(ERROR + " 4 " + e.toString());
		}
	}
/*
	public void createShape(String descriptor) {
		socketWriter.println(D_CREATE_SHAPE + descriptor + EOM);
	}
	*/
	
	@Override
	public void writeCommand(String cmd, String args) {
		if (cmd.equals("shape"))
		    socketWriter.println(D_CREATE_SHAPE + args + EOM);
		else
			System.out.println("unknown command: "+cmd+" args: "+args);
	}

	public void run() throws InterruptedException {
		log(START + name);
		setupUI();
		new ClientInputThread(socket, this).start();
		new ClientOutputThread(socket, this).start();
		while (!stop)
			Thread.sleep(1000);
		log(STOP + name);
	}

	public void exitAction() {
		if (ui != null) {
			ui.dispose();
		}
		log("exit " + name);
		exit = true;
		stop = true;
	}



}
